Racket 列表
pair
pair 包含两个值。通过 const 构建 pair。通过car 获取第一个值。通过 cdr 获取第二个值。
构建
> (cons 'x 'y)
'(x . y)
> '(10 . 20)
'(10 . 20)
可以看到 pair 的表示形式,两个值之间有一个点(.
)。
取值
> (define pair (cons 10 20))
> (car pair)
10
> (cdr pair)
20
列表 list
列表可以认为是由 pair 通过链表组合而成。
列表通常表现形式是以 '
为开头的括号,内部封装元素。
创建
> (define l (list 234 123 68 74 100 1 3 5 8 4 2))
列表操作
length 长度
> (length l)
11
list-ref 索引选择
> (list-ref (list 'a 'b 'c) 0)
'a
> (list-ref (list 'a 'b 'c) 1)
'b
> (list-ref (list 'a 'b 'c) 2)
'c
list-tail 按索引截取
> (list-tail (list 1 2 3 4 5) 2)
'(3 4 5)
> (list-tail (cons 1 2) 1)
2
append 拼接
> (append (list 1 2) (list 3 4))
'(1 2 3 4)
> (append (list 1 2) (list 3 4) (list 5 6) (list 7 8))
'(1 2 3 4 5 6 7 8)
reverse 反转
> (reverse (list 1 2 3 4))
'(4 3 2 1)
列表迭代
map 映射
> (map (lambda (i) (/ 1 i))
'(1 2 3))
'(1 1/2 1/3)
andmap 和 ormap
对每个元素,根据 lambda 进行逻辑判断:
> (andmap (lambda (i) (i . < . 3))
'(1 2 3))
#f
> (ormap (lambda (i) (i . < . 3))
'(1 2 3))
#t
for-each 遍历
> (for-each (lambda (i) (display i))
'(1 2 3))
123
foldl 和 foldr 折叠
foldl 是从左到右,foldr 是从右到左。
> (foldl (lambda (v i) (+ v i))
10
'(1 2 3))
16
foldr:
> (foldr (lambda (v l) (cons (add1 v) l)) '() '(1 2 3 4))
'(2 3 4 5)
理解:
- foldr 接收 3 个参数:一个函数,一个初始值,一个序列
- 从右往左依次对元素中每一个参数调用函数
- 并将结果与下一个参数一起再传给函数
过程:
- 取出 4,参数为 v=4 和 l='(),得到 '(5)
- 取出 3,参数为 v=3 和 l='(5),得到 '(4 5)
- 取出 2,参数为 v=2 和 l='(4 5),得到 '(3 4 5)
- 取出 1,参数为 v=1 和 l='(3 4 5),得到 '(2 3 4 5)
列表过滤
filter 过滤
> (filter (lambda (i) (i . < . 3))
'(1 2 3))
'(1 2)
remove 元素删除
删除首个遇到的元素:
> (remove 2 (list 1 2 3 2 4))
'(1 3 2 4)
> (remove '(2) (list '(1) '(2) '(3)))
'((1) (3))
> (remove "2" (list "1" "2" "3"))
'("1" "3")
> (remove #\c (list #\a #\b #\c))
'(#\a #\b)
> (remove "B" (list "a" "A" "b" "B") string-ci=?)
'("a" "A" "B")
> (remove 5 (list 1 2 3 2 4))
'(1 2 3 2 4)
remove* 元素删除
删除所有遇到的元素:
> (remove* (list 1 2) (list 1 2 3 2 4 5 2))
'(3 4 5)
sort 排序
> (sort '(1 3 4 2) <)
'(1 2 3 4)
> (sort '("aardvark" "dingo" "cow" "bear") string<?)
'("aardvark" "bear" "cow" "dingo")
> (sort '(("aardvark") ("dingo") ("cow") ("bear"))
#:key car string<?)
'(("aardvark") ("bear") ("cow") ("dingo"))
列表搜索
member 按元素截取
> (member 2 (list 1 2 3 4))
'(2 3 4)
> (member 9 (list 1 2 3 4))
#f
> (member #'x (list #'x #'y) free-identifier=?)
'(#<syntax:eval:569:0 x> #<syntax:eval:569:0 y>)
> (member #'a (list #'x #'y) free-identifier=?)
#f
> (member 'b '(a b . etc))
'(b . etc)
findf 搜索首个满足条件
> (findf (lambda (arg)
(> arg 9))
'(7 8 9 10 11))
10
assoc 条件截取
> (assoc 3 (list (list 1 2) (list 3 4) (list 5 6)))
'(3 4)
> (assoc 9 (list (list 1 2) (list 3 4) (list 5 6)))
#f
> (assoc 3.5
(list (list 1 2) (list 3 4) (list 5 6))
(lambda (a b) (< (abs (- a b)) 1)))
'(3 4)
列表附加方法
empty 空列表
> empty
'()
> (eq? empty null)
#t
empty? 是否为空
> (empty? '(1 2))
#f
> (empty? '())
#t
fisrt 获取首元素
> (first l)
234
rest 剔除首元素
> (rest l)
'(123 68 74 100 1 3 5 8 4 2)
second...tenth
获取第二、……、第十个元素。
take 取前 N 个元素
> (take l 4)
'(234 123 68 74)
drop 剔除前 N 个元素
> (drop l 4)
'(100 1 3 5 8 4 2)
在第 N 个元素处分成两半:
> (split-at l 4)
'(234 123 68 74)
'(100 1 3 5 8 4 2)
条件选取:
> (takef l even?)
'(234)
条件剔除:
> (dropf l even?)
'(123 68 74 100 1 3 5 8 4 2)
列表去重:
> (remove-duplicates '(1 2 3 2 4 5 1))
'(1 2 3 4 5)
按照条件分成两半:
> (partition (lambda (x) (< x (first l))) l)
'(123 68 74 100 1 3 5 8 4 2)
'(234)
是否是列表
通过 list?
来识别列表,通过 null?
来识别空列表。